<?php

namespace App\Remote\FuYou;

use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\RequestOptions;
use GuzzleHttp\Client;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Kuafu\File\FileUtil;
use ZipArchive;


class FuYouRemote extends FuYouBaseRemote
{

    const TM_MODE_XCH = 'JH-XCX';//富友终端型号 JH-XCX=JH-小程序
    const TM_MODE_SYJ = 'JH-SYJ';//富友终端型号 JH-SYJ=JH-收银机

    const FTP_IMG_TYPE = [//ftp图片上传
        'licenseImg'        => 'd6a4bcfed5d5c6ac.jpg',//营业执照照片
        'mchntProtocolImg'  => 'c9ccbba7d0add2e9d3d2.jpg',//商户增值协议照片
        'certifIdImg'       => 'b7a8c8cbc9edb7ddd6a4c3f7d5fdc3e6.jpg',//法人身份证正面照片
        'certifIdBackImg'   => 'b7a8c8cbc9edb7ddd6a4c3f7b7b4c3e6.jpg',//法人身份证反面照片
        'shopFrontImg'      => 'c3c5c1b3d5d5c6ac.jpg',//门脸照片-就是内设照片
        'shopHeaderImg'     => 'c3c5cdb7d5d5c6ac.jpg',    //门头照片
        'certifFlagImg'     => 'b6d4cbbdd5cbbba7c9edb7ddd6a4c3f7d5fdc3e6.jpg',   //对私账户身份证正面照片
        'certifFlagBackImg' => 'b6d4cbbdd5cbbba7c9edb7ddd6a4c3f7b1b3c3e6.jpg', //对私账户身份证反面照片
        'BankImg'           => 'd2f8d0d0bfa8d5fdc3e6.jpg',    //入账银行卡正面照片
        'certifNotFlagImg'  => 'c8ebd5cbb7c7b7a8c8cbd6a4c3f7.jpg',  //入账非法人证明照片
        'openPermitImg'     => 'bfaabba7d0edbfc9d6a4.jpg',//开户许可证照片
    ];

    /**
     *  4.1 商户信息登记接口
     * @param array $data
     * @return array
     * @throws GuzzleException
     */
    public function wxMchntAdd(array $data): array
    {
        $params = [
            'trace_no'              => time() . '00',                                                            //唯一流水号，机构自己定义，此字段可辅助拉取报文
            'ins_cd'                => $this->insCd,                                                             //机构号,接入机构在富友的唯一代码
            'mchnt_name'            => $data['mchnt_name'],                                                      //商户全称，不能有特殊字符，仅可包含汉字、数字、字母
            'mchnt_shortname'       => $data['mchnt_shortname'],                                                 //商户简称，不能有特殊字符，仅可包含汉字、数字、字母
            'real_name'             => $data['real_name'],                                                       //商户真实名称(与营业执照上相同)
            'license_type'          => $data['license_type'],                                                    //证件类型：0 企业商户：营业执照（license_no填15位长的营业执照编号）1 企业商户：三证合一（license_no填18位长的三证合一营业执照编号）A 小微商户：身份证(一证下机)B 个体户工商户（个体工商户不论证件是营业执照还是三证合一都传 B）2 事业单位
            'license_no'            => $data['license_no'],                                                      //证件号码，填写方法：1.license_type=0 或 1 或 2，此处填写营业执照号码。2.license_type=A，此处填写身份证号码3.license_type=B，此处填写个体工商户营业执照号码
            'license_expire_dt'     => $data['license_expire_dt'] ?? '20991231',                                 //证件到期日（格式yyyyMMdd）长期请填20991231，无有效期请填190001011.license_type=0 或 1 或 2，此处填写营业执照到期日。2.license_type=A，此处填写身份证的到期日3.license_type=B，此处填写个体工商户营业执照号的到期日
            'certif_id'             => $data['certif_id'],                                                       //法人身份证号
            'certif_id_expire_dt'   => $data['certif_id_expire_dt'] ?? '20991231',                               //法人身份证到期日（格式 YYYYMMDD）
            'contact_person'        => '画玖',//$this->contactPerson,                                             //联系人姓名（不能有特殊字符）
            'contact_phone'         => $this->contactMobile,                                                     //客服电话，必须纯数字。推荐 400开头电话或11位有效手机号
            'contact_addr'          => $data['contact_addr'],                                                    //商户经营地联系地址
            'contact_mobile'        => $this->contactMobile,                                                     //联系电话
            'contact_email'         => $this->contactEmail,                                                      //联系邮箱
            'business'              => $data['business'],                                                        //经营范围代码（新开户则必填）见附件4.微信经营范围代码
            'city_cd'               => $data['city_cd'],                                                         //商户经营地市代码见附件6.省市区代码对照表
            'county_cd'             => $data['county_cd'],                                                       //商户经营地区县代码（必须属于 city_cd 所辖）见附件6.省市区代码对照表
            'acnt_type'             => $data['acnt_type'],                                                       //入账卡类型：1：对公；2：对私;入账卡类型为 1 时，对公户户名需与营业执照名称保持一致（进件若为双账户时，此处必填 2 ，即对私结算）
            'bank_type'             => $data['bank_type'],                                                       //行别,（acnt_type=1 必填）(参考行别对照表)见附件7.行别对照表
            'inter_bank_no'         => $data['inter_bank_no'],                                                   //入账卡开户行联行号 对公户和城商行，农商行，农信社必填，否则影响银行卡入账。如果联行号在富友给的表格里不存在，可联系运营人员添加见附件9.开户行信息列表
            'iss_bank_nm'           => $data['iss_bank_nm'],                                                     //入账卡开户行名称见附件9.开户行信息列表
            'acnt_nm'               => $data['acnt_nm'],                                                         //入账卡户名1. 如果 license_type=A，acnt_nm=artif_nm 即小微商户身份证入网须入账法人2. 如果 acnt_type=2 且acnt_artif_flag=1，则 acnt_nm=artif_nm 即对私且法人入账，则入账卡户名和法人姓名一致3. 如果 acnt_type=1 且acnt_artif_flag=1，则 acnt_nm=real_name 即对公且法人入账，则入账卡户名和营业执照上商户名一致
            'acnt_no'               => $data['acnt_no'],                                                         //入账卡号（不带长度位）
            'settle_tp'             => '1',                                                                      //清算类型：1 自动结算（T1）
            'artif_nm'              => $data['artif_nm'],                                                        //法人姓名（如果 acnt_type=2 且acnt_artif_flag=1，则 acnt_nm=artif_nm 即对私且法人入账，则入账卡户名和法人姓名一致）
            'acnt_artif_flag'       => $data['acnt_artif_flag'],                                                 //法人入账标识 0 :非法人入账，1：法人入账 若license_type=A，这此字段必须填：1：法人入账
            'acnt_certif_tp'        => $data['acnt_certif_tp'],                                                  //入账证件类型("0":"身份证"【默认】【acnt_artif_flag = 0 时必填】
            'acnt_certif_expire_dt' => $data['acnt_certif_expire_dt'] ?? '20991231',                             //入账证件到期日（格式 yyyyMMdd）license_type=A，这里的值acnt_certif_expire_dt=license_expire_dt
            'acnt_certif_id'        => $data['acnt_certif_id'],                                                  //入账证件号【acnt_artif_flag = 0时必填】1.如果 license_type=A，则acnt_certif_id =license_no 即小微商户身份证入网须入账人身份证号码即法人身份证号码2.如果 acnt_type=2 且acnt_artif_flag=1，则acnt_certif_id =certif_id 即对私且法人入账，则入账卡人身份证号码和法人身份证号码一致
            "card_start_dt"         => $data['card_start_dt'],                                                   //法人身份证开始时间(2021年9月10日后必填)
            "contact_cert_no"       => $data['contact_cert_no'],                                                 //联系人身份证号(9月10日后必填)
            "lic_regis_addr"        => $data['lic_regis_addr'],                                                  //营业执照注册地址
            "license_start_dt"      => $data['license_start_dt'],                                                //营业执照开始时间
            "wx_busi_flag"          => '0',                                                                      //微信业务标识(0：微信一般类)
            "wx_flag"               => '1',                                                                      //微信支付标识（0：不开通，1：开通）
            "wx_set_cd"             => $this->wxSetCd,                                                           //微信扣率套餐代码(如果wx_flag=1，则必填)
            "ali_flag"              => '1',                                                                      //支付宝支付标识（0：不开通，1：开通）
            "ali_set_cd"            => $this->aliSetCd,                                                          //支付宝扣率套餐代码(如果ali_flag=1，则必填)
            'acnt_contact_mobile'   => $data['acnt_contact_mobile'],                                             //对私户入账手机号
            "has_reserve_acnt"      => $data['has_reserve_acnt'] ?? '',                                          //是否有备用对公银行账号(1：有，0：没有)
            "reserve_acnt_no"       => $data['reserve_acnt_no'] ?? '',                                           //双账户对公卡卡号
            "reserve_acnt_nm"       => $data['reserve_acnt_nm'] ?? '',                                           //双账户对公卡户名
            "reserve_inter_bank_no" => $data['reserve_inter_bank_no'] ?? '',                                     //双账户对公卡联行号
            "reserve_iss_bank_nm"   => $data['reserve_iss_bank_nm'] ?? '',                                       //双账户对公卡开户行名称
            "reserve_bank_type"     => $data['reserve_bank_type'] ?? '',                                         //双账户对公卡行别
        ];

//        $url         = $this->defaultUrl . '?action=wxMchntAdd';
//        $responseStr = self::postDataXml($url, $params, 'GBK', 1);
        $url         = $this->defaultUrl . '?action=wxMchntAddU8';
        $responseStr = self::postDataXmlU8($url, $params, 1);
        Log::info("富友4.1 商户信息登记接口请求返回：", ['url' => $url, 'data' => $data, 'responseStr' => $responseStr]);
        return $responseStr;
    }


    /**
     * 4.2 商户信息更新接口
     * @param array $data
     * @return array
     * @throws GuzzleException
     */
    public function wxMchntUpd(array $data = []): array
    {
        $params = [
            'trace_no'              => time() . '01',                                                                                                                               //唯一流水号，机构自己定义，此字段可辅助拉取报文
            'fy_mchnt_cd'           => $data['fy_mchnt_cd'],                                                                                                                        //已在富友入网的富友商户代码
            'ins_cd'                => $this->insCd,                                                                                                                                //机构号,接入机构在富友的唯一代码
            'mchnt_name'            => $data['mchnt_name'] ?? '',                                                                                                                   //商户全称，不能有特殊字符，仅可包含汉字、数字、字母
            'mchnt_shortname'       => $data['mchnt_shortname'] ?? '',                                                                                                              //商户简称，不能有特殊字符，仅可包含汉字、数字、字母
            'real_name'             => $data['real_name'] ?? '',                                                                                                                    //商户真实名称(与营业执照上相同)
            'license_type'          => $data['license_type'] ?? '',                                                                                                                 //证件类型：0 企业商户：营业执照（license_no填15位长的营业执照编号）1 企业商户：三证合一（license_no填18位长的三证合一营业执照编号）A 小微商户：身份证(一证下机)B 个体户工商户（个体工商户不论证件是营业执照还是三证合一都传 B）2 事业单位
            'license_no'            => $data['license_no'] ?? '',                                                                                                                   //证件号码，填写方法：1.license_type=0 或 1 或 2，此处填写营业执照号码。2.license_type=A，此处填写身份证号码3.license_type=B，此处填写个体工商户营业执照号码
            'license_expire_dt'     => $data['license_expire_dt'] ?? '',                                                                                                            //证件到期日（格式yyyyMMdd）长期请填20991231，无有效期请填190001011.license_type=0 或 1 或 2，此处填写营业执照到期日。2.license_type=A，此处填写身份证的到期日3.license_type=B，此处填写个体工商户营业执照号的到期日
            'certif_id'             => $data['certif_id'] ?? '',                                                                                                                    //法人身份证号
            'certif_id_expire_dt'   => $data['certif_id_expire_dt'] ?? '',                                                                                                          //法人身份证到期日（格式 YYYYMMDD）
            'city_cd'               => $data['city_cd'] ?? '',                                                                                                                      //商户经营地市代码见附件6.省市区代码对照表
            'county_cd'             => $data['county_cd'] ?? '',                                                                                                                    //商户经营地区县代码（必须属于 city_cd 所辖）见附件6.省市区代码对照表
            'contact_person'        => $data['contact_person'] ?? '',                                                                                                               //联系人姓名（不能有特殊字符）
            'contact_phone'         => $data['contact_phone'] ?? '',                                                                                                                //客服电话，必须纯数字。推荐 400开头电话或11位有效手机号
            'contact_addr'          => $data['contact_addr'] ?? '',                                                                                                                 //商户经营地联系地址
            'contact_mobile'        => $data['contact_mobile'] ?? '',                                                                                                               //联系电话
            'contact_email'         => $data['contact_email'] ?? '',                                                                                                                //联系邮箱
            'business'              => $data['business'] ?? '',                                                                                                                     //经营范围代码（新开户则必填）见附件4.微信经营范围代码
            'acnt_type'             => $data['acnt_type'] ?? '',                                                                                                                    //入账卡类型：1：对公；2：对私;入账卡类型为 1 时，对公户户名需与营业执照名称保持一致（进件若为双账户时，此处必填 2 ，即对私结算）
            'bank_type'             => $data['bank_type'] ?? '',                                                                                                                    //行别,（acnt_type=1 必填）(参考行别对照表)见附件7.行别对照表
            'inter_bank_no'         => $data['inter_bank_no'] ?? '',                                                                                                                //入账卡开户行联行号 对公户和城商行，农商行，农信社必填，否则影响银行卡入账。如果联行号在富友给的表格里不存在，可联系运营人员添加见附件9.开户行信息列表
            'iss_bank_nm'           => $data['iss_bank_nm'] ?? '',                                                                                                                  //入账卡开户行名称见附件9.开户行信息列表
            'acnt_nm'               => $data['acnt_nm'] ?? '',                                                                                                                      //入账卡户名1. 如果 license_type=A，acnt_nm=artif_nm 即小微商户身份证入网须入账法人2. 如果 acnt_type=2 且acnt_artif_flag=1，则 acnt_nm=artif_nm 即对私且法人入账，则入账卡户名和法人姓名一致3. 如果 acnt_type=1 且acnt_artif_flag=1，则 acnt_nm=real_name 即对公且法人入账，则入账卡户名和营业执照上商户名一致
            'acnt_no'               => $data['acnt_no'] ?? '',                                                                                                                      //入账卡号（不带长度位）
            'settle_tp'             => $data['settle_tp'] ?? '',                                                                                                                    //清算类型：1 自动结算（T1）
            'artif_nm'              => $data['artif_nm'] ?? '',                                                                                                                     //法人姓名（如果 acnt_type=2 且acnt_artif_flag=1，则 acnt_nm=artif_nm 即对私且法人入账，则入账卡户名和法人姓名一致）
            'acnt_artif_flag'       => $data['acnt_artif_flag'] ?? '',                                                                                                              //法人入账标识 0 :非法人入账，1：法人入账 若license_type=A，这此字段必须填：1：法人入账
            'acnt_certif_tp'        => $data['acnt_certif_tp'] ?? '',                                                                                                               //入账证件类型("0":"身份证"【默认】【acnt_artif_flag = 0 时必填】
            'acnt_certif_expire_dt' => $data['acnt_certif_expire_dt'] ?? '',                                                                                                        //入账证件到期日（格式 yyyyMMdd）license_type=A，这里的值acnt_certif_expire_dt=license_expire_dt
            'acnt_certif_id'        => $data['acnt_certif_id'] ?? '',                                                                                                               //入账证件号【acnt_artif_flag = 0时必填】1.如果 license_type=A，则acnt_certif_id =license_no 即小微商户身份证入网须入账人身份证号码即法人身份证号码2.如果 acnt_type=2 且acnt_artif_flag=1，则acnt_certif_id =certif_id 即对私且法人入账，则入账卡人身份证号码和法人身份证号码一致
            "card_start_dt"         => $data['card_start_dt'] ?? '',                                                                                                                //法人身份证开始时间(2021年9月10日后必填)
            "contact_cert_no"       => $data['contact_cert_no'] ?? '',                                                                                                              //联系人身份证号(9月10日后必填)
            "lic_regis_addr"        => $data['lic_regis_addr'] ?? "",                                                                                                               //营业执照注册地址
            "license_start_dt"      => $data['license_start_dt'] ?? '',                                                                                                             //营业执照开始时间
            "wx_busi_flag"          => $data['wx_busi_flag'] ?? '',                                                                                                                 //微信业务标识(0：微信一般类)
            "wx_flag"               => $data['wx_flag'] ?? "",                                                                                                                      //微信支付标识（0：不开通，1：开通）
            "wx_set_cd"             => $this->wxSetCd,                                                                                                                              //微信扣率套餐代码(如果wx_flag=1，则必填)
            "ali_flag"              => $data['ali_flag'] ?? "",                                                                                                                     //支付宝支付标识（0：不开通，1：开通）
            "ali_set_cd"            => $this->aliSetCd,                                                                                                                             //支付宝扣率套餐代码(如果ali_flag=1，则必填)
        ];

        $url         = $this->defaultUrl . '?action=wxMchntUpd';
        $responseStr = self::postDataXml($url, $params, 'GBK', 1);

        Log::info("富友4.2 商户信息更新接口请求返回：", ['url' => $url, 'data' => $data, 'responseStr' => $responseStr]);
        return $responseStr;
    }

    /**
     * 4.2.1 入账信息变更接口
     * 此接口不支持变更入账卡类型
     * 此接口可用于双账户入账信息信息变更
     * @param array $data
     * @return array
     * @throws GuzzleException
     */
    public function mchntAcntUpd(array $data = []): array
    {
        $params = [
            'trace_no'              => time() . '02',                                                                                         //唯一流水号，机构自己定义，此字段可辅助拉取报文
            'fy_mchnt_cd'           => $data['fy_mchnt_cd'],                                                                                  //已在富友入网的富友商户代码
            'ins_cd'                => $data['ins_cd'] ?? $this->insCd,                                                                       //机构号,接入机构在富友的唯一代码
            'bank_type'             => $data['bank_type'] ?? '',                                                                              //行别,（acnt_type=1 必填）(参考行别对照表)见附件7.行别对照表
            'inter_bank_no'         => $data['inter_bank_no'] ?? '',                                                                          //入账卡开户行联行号 对公户和城商行，农商行，农信社必填，否则影响银行卡入账。如果联行号在富友给的表格里不存在，可联系运营人员添加见附件9.开户行信息列表
            'iss_bank_nm'           => $data['iss_bank_nm'] ?? '',                                                                            //入账卡开户行名称见附件9.开户行信息列表
            'acnt_type'             => $data['acnt_type'] ?? '',                                                                              //入账卡类型：1：对公；2：对私;入账卡类型为 1 时，对公户户名需与营业执照名称保持一致（进件若为双账户时，此处必填 2 ，即对私结算）
            'acnt_nm'               => $data['acnt_nm'] ?? '',                                                                                //入账卡户名1. 如果 license_type=A，acnt_nm=artif_nm 即小微商户身份证入网须入账法人2. 如果 acnt_type=2 且acnt_artif_flag=1，则 acnt_nm=artif_nm 即对私且法人入账，则入账卡户名和法人姓名一致3. 如果 acnt_type=1 且acnt_artif_flag=1，则 acnt_nm=real_name 即对公且法人入账，则入账卡户名和营业执照上商户名一致
            'acnt_no'               => $data['acnt_no'] ?? '',                                                                                //入账卡号（不带长度位）
            'acnt_artif_flag'       => $data['acnt_artif_flag'] ?? '',                                                                        //法人入账标识 0 :非法人入账，1：法人入账 若license_type=A，这此字段必须填：1：法人入账
            'acnt_certif_tp'        => $data['acnt_certif_tp'] ?? '',                                                                         //入账证件类型("0":"身份证"【默认】【acnt_artif_flag = 0 时必填】
            'acnt_certif_id'        => $data['acnt_certif_id'] ?? '',                                                                         //入账证件号【acnt_artif_flag = 0时必填】1.如果 license_type=A，则acnt_certif_id =license_no 即小微商户身份证入网须入账人身份证号码即法人身份证号码2.如果 acnt_type=2 且acnt_artif_flag=1，则acnt_certif_id =certif_id 即对私且法人入账，则入账卡人身份证号码和法人身份证号码一致
            'acnt_certif_expire_dt' => $data['acnt_certif_expire_dt'] ?? '',                                                                  //入账证件到期日（格式 yyyyMMdd）license_type=A，这里的值acnt_certif_expire_dt=license_expire_dt
            'acnt_contact_mobile'   => $data['acnt_contact_mobile'] ?? '',                                                                    //对私户入账手机号
            'modify_desc'           => $data['modify_desc'] ?? '',                                                                            //变更描述即变更备注，富友在审核时，可以看到的文字描述
        ];

        $url         = $this->mchntUrl . '?action=mchntAcntUpd';
        $responseStr = self::postDataXml($url, $params, 'GBK', 1);

        Log::info("富友4.2.1 入账信息变更接口请求返回：", ['url' => $url, 'data' => $data, 'responseStr' => $responseStr]);
        return $responseStr;
    }


    /**
     * 4.3 商户名称判重接口
     * 此接口不做验签，不能以此接口返回的验签结果为标准来判断其他接口
     * @param array $data
     * @return array
     * @throws GuzzleException
     */
    public function wxMchntNameCheck(array $data = []): array
    {
        $params = [
            'trace_no'    => time() . '03',                                                                                         //唯一流水号，机构自己定义，此字段可辅助拉取报文
            'fy_mchnt_cd' => $data['fy_mchnt_cd'],                                                                                  //已在富友入网的富友商户代码
            'mchnt_name'  => $data['mchnt_name'],                                                                                   //机构号,接入机构在富友的唯一代码
        ];

        $url         = $this->defaultUrl . '?action=wxMchntNameCheck';
        $responseStr = self::postDataXml($url, $params);

        Log::info("富友4.3 商户名称判重接口请求返回：", ['url' => $url, 'data' => $data, 'responseStr' => $responseStr]);
        return $responseStr;
    }

    /**
     * 4.4 微信参数配置接口
     * @param array $data
     * @return array
     * @throws GuzzleException
     */
    public function xyWechatConfigSet(array $data = []): array
    {
        $params = [
            'traceNo'    => time() . '04',                                                              //唯一流水号，机构自己定义，此字段可辅助拉取报文
            'insCd'      => $this->insCd,                                                               //机构号,接入机构在富友的唯一代码
            'agencyType' => $data['agencyType'] ?? '0',                                                 //代理商类型(0：一般类，1：绿洲)
            'configs'    => [                                                                                                                 //配置列表（参数如下）
                [
                    'mchntCd'        => $data['configs']['mchntCd'],                                                                                                                                    //富友商户号
                    'jsapiPath'      => $data['configs']['jsapiPath'] ?? '',                                                                                                                            //JSAPI 支付授权目录
                    'subAppid'       => $data['configs']['subAppid'] ?? '',                                                                                                                             //子商户 SubAPPID
                    'subscribeAppid' => $data['configs']['subscribeAppid'] ?? '',                                                                                                                       //子商户推荐关注公众账号 APPID
                ]
            ],
        ];

        $url         = $this->defaultUrl . '?action=xyWechatConfigSet';
        $responseStr = self::postData($url, $params);

        Log::info("富友4.4 微信参数配置接口请求返回：", ['url' => $url, 'data' => $data, 'responseStr' => $responseStr]);
        return $responseStr;
    }

    /**
     * 4.5 微信参数查询接口
     * @param array $data
     * @return array
     * @throws GuzzleException
     */
    public function xyWechatConfigGet(array $data = []): array
    {
        $params = [
            'traceNo'    => time() . '05',                                                      //唯一流水号，机构自己定义，此字段可辅助拉取报文
            'insCd'      => $this->insCd,                                                       //机构号,接入机构在富友的唯一代码
            'agencyType' => $data['agencyType'] ?? '0',                                         //代理商类型(0：一般类，1：绿洲)
            'configs'    => [                                                                                                                 //配置列表（参数如下）
                [
                    'mchntCd' => $data['mchntCd'],                                                                                                        //富友商户号
                ]
            ],
        ];

        $url         = $this->defaultUrl . '?action=xyWechatConfigGet';
        $responseStr = self::postData($url, $params);

        Log::info("富友4.5 微信参数查询接口请求返回：", ['url' => $url, 'data' => $data, 'responseStr' => $responseStr]);
        return $responseStr;

    }


    /**
     * 4.8 附件提交完成接口(重要接口)
     * 接口用于在附件上传完成之后，通知富友进行商户审核
     * @param array $data
     * @return array
     * @throws GuzzleException
     */
    public function attachConfirm(array $data = []): array
    {
        $params = [
            'trace_no'             => time() . '06',                                                                            //唯一流水号，机构自己定义，此字段可辅助拉取报文
            'ins_cd'               => $this->insCd,                                                                             //机构号,接入机构在富友的唯一代码
            'mchnt_cd'             => $data['mchnt_cd'],                                                                        //商户号
            'push_openaccount_sms' => '1',                                                                                      //发送账密短信标识，默认不发0不发 1发送
        ];

        $url         = $this->defaultUrl . '?action=attachConfirm';
        $responseStr = self::postData($url, $params);

        Log::info("富友4.8 附件提交完成接口(重要接口)请求返回：", ['url' => $url, 'data' => $data, 'responseStr' => $responseStr]);
        return $responseStr;

    }


    /**
     * 测试地址： 主机地址:ftp-1.fuiou.com 端口：9021 用户名:FTP999999 密码：8A4GL0qVNd4RWhtK
     * 压缩方式：zip格式
     * 压缩包命名方式：富友商户号.zip 如 0002900F0319983 .zip
     * 文件结构：将需上传附件 直接压缩至压缩包，无文件夹
     * 文件命名方式：图片文件直接命名为图片类型对应的名称。文件名见 “文件命名对照表”
     * 文件类型目前支持.jpg
     * 文件大小限制：单个附件大小不超过 1MB ，整个压缩包暂不限制大小
     * @param $mchntCd
     * @return bool
     */
    public function actionFtpUpImg($mchntCd): bool
    {
        //测试地址： 主机地址:ftp-1.fuiou.com 端口：9021 用户名:FTP999999 密码：8A4GL0qVNd4RWhtK
        $conn = ftp_connect($this->ftpIp, $this->ftpPort) or die("Could not connect");
        $login = ftp_login($conn, $this->ftpUserName, $this->ftpPassword);
        $res   = true;
        if ($login) {
            ftp_pasv($conn, true);//FTP被动模式（PASV模式）
            $path = public_path() . '/storage/fuyou/' . $mchntCd . '/' . $mchntCd . '.zip';
            //开始上传
            $res = ftp_put($conn, $mchntCd . '.zip', $path, FTP_BINARY);
            //上传成功
        } else {
            Log::info("富友图片FTP上传登陆请求返回失败：", ['res' => false, 'conn' => $conn]);
        }
        ftp_close($conn);
        //注意上传端的ftp权限设置
        return $res;
    }


    /**
     * 4.9 商户图片上传
     * 下载图片到本地，压缩，改jpg格式，重命名文件名
     * @param array $data
     * @return string
     */
    public function ftpUpImg(array $data = [])
    {
        $params = [
            'mchntCd'           => $data['mchnt_cd'],                                                                                                //商户号
            'licenseImg'        => $data['licenseImg'] ?? '',                                                                                        //营业执照照片 d6a4bcfed5d5c6ac.jpg
            'mchntProtocolImg'  => $data['mchntProtocolImg'] ?? '',                                                                                  //商户增值协议照片	 c9ccbba7d0add2e9d3d2.jpg
            'certifIdImg'       => $data['certifIdImg'] ?? '',                                                                                       //法人身份证正面照片	 b7a8c8cbc9edb7ddd6a4c3f7d5fdc3e6.jpg
            'certifIdBackImg'   => $data['certifIdBackImg'] ?? '',                                                                                   //法人身份证反面照片	 b7a8c8cbc9edb7ddd6a4c3f7b7b4c3e6.jpg
            'shopFrontImg'      => $data['shopFrontImg'] ?? '',                                                                                      //门脸照片-就是内设照片		 c3c5c1b3d5d5c6ac.jpg
            'shopHeaderImg'     => $data['shopHeaderImg'] ?? '',                                                                                     //门头照片	 c3c5cdb7d5d5c6ac.jpg
            'certifFlagImg'     => $data['certifFlagImg'] ?? '',                                                                                     //对私账户身份证正面照片	acnt_artif_flag=0 必填 b6d4cbbdd5cbbba7c9edb7ddd6a4c3f7d5fdc3e6.jpg
            'certifFlagBackImg' => $data['certifFlagBackImg'] ?? '',                                                                                 //对私账户身份证反面照片	acnt_artif_flag=0 必填 b6d4cbbdd5cbbba7c9edb7ddd6a4c3f7b1b3c3e6.jpg
            'BankImg'           => $data['BankImg'] ?? '',                                                                                           //入账银行卡正面照片		 d2f8d0d0bfa8d5fdc3e6.jpg
            'certifNotFlagImg'  => $data['certifNotFlagImg'] ?? '',                                                                                  //入账非法人证明照片		 c8ebd5cbb7c7b7a8c8cbd6a4c3f7.jpg
            'openPermitImg'     => $data['openPermitImg'] ?? '',                                                                                     //开户许可证照片	1.acnt_type=1必填2.license_type=0或1的情况即营业执照或营业执照（三证合一）入网的必填	 bfaabba7d0edbfc9d6a4.jpg
        ];//将多个图片下载保存到本地进行压缩，转格式
        $downPath = public_path() . '/storage/fuyou/' . $params['mchntCd'];//文件路径
        self::mkdirs($downPath);//创建文件夹
        //下载图片
        foreach ($params as $k => $v) {
//压缩            ?x-oss-process=image/resize,m_fill,h_300/format
            if (in_array($k, array_keys(self::FTP_IMG_TYPE)) && $v != '') {
                $fileName = self::FTP_IMG_TYPE[$k];
                $res      = self::downLoad($v, $downPath, $fileName);
            }
        }

        //将多个图片压缩打包
        $filename = $downPath . '/' . $params['mchntCd'] . ".zip";// 压缩包存放路径与名称
        self::addFileToZip($filename, array_values(self::FTP_IMG_TYPE), $downPath);

        Log::info("富友4.9 商户图片上传请求返回：", ['data' => $params, 'res' => $downPath]);
        //上传压缩包
        return self::actionFtpUpImg($params['mchntCd']);
    }


    /**
     * 4.16 银联二维码业务申请开通接口
     * @param array $data
     * @return array
     * @throws GuzzleException
     */
    public function mchntOpenUpayQr(array $data = []): array
    {
        $params = [
            'trace_no'           => time() . '07',                                                                                           //唯一流水号，机构自己定义，此字段可辅助拉取报文
            'ins_cd'             => $this->insCd,                                                                                            //机构号,接入机构在富友的唯一代码
            'mchnt_cd'           => $data['mchnt_cd'] ,                                                                  //商户号
            "print_receipt"      => $data['print_receipt'] ?? '凭条',                                                                         //银联凭条打印名称
            "debit_card_set_cd"  => $data['debit_card_set_cd'] ?? 'M0128',                                                                   //借记卡扣率
            "credit_card_set_cd" => $data['credit_card_set_cd'] ?? 'M0128',                                                                  //贷记卡扣率
            "mchnt_sub_tp"       => $data['mchnt_sub_tp'] ?? '5814',                                                                         //商户子类型
        ];

        $url         = $this->defaultUrl . '?action=mchntOpenUpayQr';
        $responseStr = self::postDataXml($url, $params);

        Log::info("富友4.16 银联二维码业务申请开通接口请求返回：", ['url' => $url, 'data' => $data, 'responseStr' => $responseStr]);
        return $responseStr;

    }

    /**
     * 4.18 商户渠道子商户号查询接口
     * @param array $data
     * @return array
     * @throws GuzzleException
     */
    public function chnlSubMchIdQuery(array $data = []): array
    {
        $params = [
            'trace_no' => time() . '08',                                                                             //唯一流水号，机构自己定义，此字段可辅助拉取报文
            'ins_cd'   => $this->insCd,                                                                              //机构号,接入机构在富友的唯一代码
            'mchnt_cd' => $data['mchnt_cd'],                                                                         //商户号
            "mchnt_tp" => $data['mchnt_tp'] ?? '1',                                                                  //1:微信2：支付宝3：微信绿洲4：支付宝蓝海5：翼支付6：银联二维码
        ];

        $url         = $this->defaultUrl . '?action=chnlSubMchIdQuery';
        $responseStr = self::postDataXml($url, $params);

        Log::info("富友4.18 商户渠道子商户号查询接口请求返回：", ['url' => $url, 'data' => $data, 'responseStr' => $responseStr]);
        return $responseStr;

    }


    /**
     * 4.19 商户信息查询接口
     * @param array $data
     * @return array
     * @throws GuzzleException
     */
    public function getMchntInfAndConfig(array $data = []): array
    {
        $params = [
            'traceNo' => time() . '09',                                                                                                                                //唯一流水号，机构自己定义，此字段可辅助拉取报文
            'insCd'   => $this->insCd,                                                                                                                                 //机构号,接入机构在富友的唯一代码
            'mchntCd' => $data['mchntCd'],                                                                                                                             //商户号
        ];

        $url         = $this->defaultUrl . '?action=getMchntInfAndConfig';
        $responseStr = self::postData($url, $params);

        Log::info("富友4.19 商户信息查询接口请求返回：", ['url' => $url, 'data' => $data, 'responseStr' => $responseStr]);
        return $responseStr;
    }

    /**
     * 4.21 微信认证查询接口
     * 建议调用 4.19 接口查询到微信子商户号进行查询
     * @param array $data
     * @return array
     * @throws GuzzleException
     */
    public function wxAuthQuery(array $data = []): array
    {
        $params = [
            'trace_no' => time() . '10',                                                                             //唯一流水号，机构自己定义，此字段可辅助拉取报文
            'ins_cd'   => $this->insCd,                                                                              //机构号,接入机构在富友的唯一代码
            'mchnt_cd' => $data['mchnt_cd'],                                                                         //商户号
        ];

        $url         = $this->defaultUrl . '?action=wxAuthQuery';
        $responseStr = self::postDataXml($url, $params, 'gbk');

        Log::info("富友4.21 微信认证查询接口请求返回：", ['url' => $url, 'data' => $data, 'responseStr' => $responseStr]);

        return $responseStr;
    }

    /**
     * 4.22 商户查询支付宝渠道信息
     * @param array $data
     * @return array
     * @throws GuzzleException
     */
    public function aliQueryMchChnlInf(array $data = []): array
    {
        $params = [
            'trace_no' => time() . '11',                                                                             //唯一流水号，机构自己定义，此字段可辅助拉取报文
            'ins_cd'   => $this->insCd,                                                                              //机构号,接入机构在富友的唯一代码
            'mchnt_cd' => $data['mchnt_cd'],                                                                         //申请商户号，与smid二选一，或者两者都上送
            'smid'     => $data['smid'] ?? '',                                                                       //支付宝smid，与mchnt_cd二选一，或者两者都上送
        ];

        $url         = $this->defaultUrl . '?action=aliQueryMchChnlInf';
        $responseStr = self::postDataXml($url, $params, 'GBK', 1);

        Log::info("富友4.22 商户查询支付宝渠道信息请求返回：", ['url' => $url, 'data' => $data, 'responseStr' => $responseStr]);
        return $responseStr;
    }


    /**
     * 4.24 商户终端信息采集报备接口
     * 测试地址： http://www-1.fuiou.com:28090/wmp/term.fuiou?action=termCollect
     * 生产地址： https://mchntapi.fuioupay.com/term.fuiou?action=termCollect
     * @param array $data
     * @return array
     * @throws GuzzleException
     */
    public function termCollect(array $data = []): array
    {
        $params = [
            'trace_no'        => time() . '12',                                                                                                         //唯一流水号，机构自己定义，此字段可辅助拉取报文
            'ins_cd'          => $this->insCd,                                                                                                          //机构号,接入机构在富友的唯一代码
            'mchnt_cd'        => $data['mchnt_cd'],                                                                                                     //商户号
            "handle_type"     => $data['handle_type'] ?? '00',                                                                                          //操作标识，取值范围：00：新增；01：修改；02：注销；
            'tm_mode'         => $data['tm_mode'] ?? self::TM_MODE_SYJ,                                                                                 //富友终端型号 JH-XCX=JH-小程序,JH-SYJ=JH-收银机
            'tm_device_state' => $data['tm_device_state'] ?? '00',                                                                                      //终端设备状态(启用、注销)00：启用；01：注销；
            'tm_serial_no'    => $data['tm_serial_no'],                                                                                                 //如果厂家没有TUSN或者没有实体终端，本字段则填写：[mchnt_cd + SN号]或者[mchnt_cd + 合作方的虚拟终端号] eg:0002900F04686310000000001 此字段后续填入交易的reserved_terminal_info.serial_num字段中。
            'tm_contact_addr' => $data['tm_contact_addr'],                                                                                              //终端布放地(省-市-区-详细地址)
        ];

        $url         = $this->termUrl . '?action=termCollect';
        $responseStr = self::postDataXml($url, $params);

        Log::info("富友4.24 商户终端信息采集报备接口请求返回：", ['url' => $url, 'data' => $data, 'responseStr' => $responseStr]);
        return $responseStr;
    }


    /**
     * 请求数据-json
     * @param string $url
     * @param array $postData
     * @return array
     * @throws GuzzleException
     */
    public function postData(string $url, array $postData): array
    {
        $postData['sign'] = self::getSign($postData);
        $response         = (new Client(
            [
                RequestOptions::TIMEOUT => 120,
                RequestOptions::VERIFY  => false,
            ]
        ))->post($url, ['form_params' => ['req' => json_encode($postData)]]);
        $body             = $response->getBody()->getContents();
        Log::info("富友json接口请求返回：", ['url' => $url, 'postData' => $postData, 'form_params' => ['req' => json_encode($postData)], 'body' => json_decode($body, true)]);

        return json_decode($body, true);
    }

    /**
     * 请求数据-xml
     * @param string $url
     * @param array $postData
     * @param string $dataCode
     * @param int $flagSign
     * @return array
     * @throws GuzzleException
     */
    public function postDataXml(string $url, array $postData, $dataCode = 'GBK', $flagSign = 0): array
    {
        $strGBK           = mb_convert_encoding($postData, 'GBK', 'utf-8');
        $postData         = $strGBK;
        $postData['sign'] = $flagSign == 0 ? self::getSign($postData) : self::hmacSign($postData);
        $postDataXml      = self::toXml($postData);
        //dd($postDataXml);
        $response = (new Client(
            [
                RequestOptions::TIMEOUT => 120,
                RequestOptions::VERIFY  => false
            ]
        ))->post($url, ['form_params' => ['req' => urlencode($postDataXml)]]);

        $result      = urldecode($response->getBody()->getContents());
        $strUTF8     = mb_convert_encoding($result, 'utf-8', 'gb2312');
        $responseStr = str_replace($dataCode, 'utf-8', $strUTF8);
        $responseStr = simplexml_load_string($responseStr);
        $result      = json_decode(json_encode($responseStr), true);
        Log::info("富友xml接口请求返回：", ['url' => $url, 'postData' => $postData, 'form_params' => ['req' => urlencode($postDataXml)], 'result' => $result]);
        return $result;

    }


    /**
     * @param string $url
     * @param array $postData
     * @param int $flagSign
     * @return array
     * @throws GuzzleException
     */
    public function postDataXmlU8(string $url, array $postData, int $flagSign = 0): array
    {
        $postData['sign'] = $flagSign == 0 ? self::getSign($postData) : self::hmacSign($postData);
        $postDataXml      = self::toXml($postData,'utf-8');
        $response = (new Client(
            [
                RequestOptions::TIMEOUT => 120,
                RequestOptions::VERIFY  => false
            ]
        ))->post($url, ['form_params' => ['req' => urlencode($postDataXml)]]);

        $result      = urldecode($response->getBody()->getContents());
        Log::info('富友xml接口请求返回U8原始返回:',[
            'url'=>$url,'postData'=>$postData,'result'=>$result,'resultOri'=>$response->getBody()->getContents()
        ]);
        $responseStr = simplexml_load_string($result);
        $result      = json_decode(json_encode($responseStr), true);
        Log::info("富友xml接口请求返回U8：", [
            'url' => $url, 'postData' => $postData, 'postDataXml'=>$postDataXml,
            'form_params' => ['req' => urlencode($postDataXml)], 'result' => $result
        ]);
        return $result;
    }

    /**
     * 获取签名
     * @param $params
     * @return string
     */
    public function getSign($params): string
    {
        ksort($params);
        $params['key'] = $this->key;
        $paramsString  = http_build_query($params);
        $paramsString  = urldecode($paramsString);
        return md5($paramsString);
    }

    /**
     * XML编码
     * @param mixed $data 数据
     * @param string $encoding 数据编码
     * @param string $root 根节点名
     * @return string
     */
    public function toXml($data, $encoding = 'GBK', $root = 'xml'): string
    {
        $xml = '<?xml version="1.0" encoding="' . $encoding . '" standalone="yes"?>';
        $xml .= '<' . $root . '>';
        $xml .= self::data2xml($data);
        $xml .= '</' . $root . '>';
        return $xml;
    }

    /**
     * 数据XML编码
     * @param mixed $data 数据
     * @return string
     */
    public function data2xml($data): string
    {
        $xml = '';
        foreach ($data as $key => $val) {
            is_numeric($key) && $key = "item id=\"$key\"";
            $xml .= "<$key>";
            $xml .= (is_array($val) || is_object($val)) ? self::data2xml($val) : $val;
            list($key,) = explode(' ', $key);
            $xml .= "</$key>";
        }
        return $xml;
    }

    /**
     * 密钥
     * @param $params
     * @return string
     */
    public function hmacSign($params): string
    {
        ksort($params);
        $params['key'] = $this->key;
        $paramsString  = "";
        foreach ($params as $k => $v) {
            if ($v !== "") {
                if (is_array($v)) {
                    $data = "";
                    foreach ($v as $vv) {
                        ksort($vv);
                        $data .= json_encode($vv);
                        $data = str_replace('"', '', $data) . ',';
                    }
                    $data         = substr($data, 0, -1);
                    $paramsString .= $k . '=[' . $data . ']&';
                } else {
                    $paramsString .= $k . '=' . $v . '&';
                }
            }
        }
        $paramsString = substr($paramsString, 0, -1);

        return md5($paramsString);
    }


    /**
     * 新建目录
     * @param $dir
     * @param int $mode
     * @return bool
     */
    public function mkdirs($dir, $mode = 0777): bool
    {
        if (is_dir($dir) || @mkdir($dir, $mode)) return TRUE;
        if (!self::mkdirs(dirname($dir), $mode)) return FALSE;

        return @mkdir($dir, $mode);
    }

    /**
     * 将多个图片压缩保存zip压缩包
     * @param $filename
     * @param $fileList
     * @param $downPath
     */
    public function addFileToZip($filename, $fileList, $downPath)
    {
        $zip = new ZipArchive();
        if ($zip->open($filename, ZipArchive::CREATE) === true) {
            // 将指定文件添加到zip中
            foreach ($fileList as $v) {
                $zip->addFile($downPath . '/' . $v, $v);
            }
            // 关闭zip文件
            $zip->close();
        }
    }


    /**
     * 下载图片
     * @param string $fileUrl 文件远程路径
     * @param string $downPath 本地保存绝对路径
     * @param string $fileName
     * @return bool
     */
    public function downLoad(string $fileUrl, string $downPath, string $fileName): bool
    {
        $ch = curl_init($fileUrl);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1);
        $rawdata = curl_exec($ch);
        curl_close($ch);
        $fp = fopen($downPath . '/' . $fileName, 'w');
        fwrite($fp, $rawdata);
        fclose($fp);
        // 返回路径
        return true;
    }

    /**
     * 4.2.2 入账信息变更接口v2(先使用统一图片上传，在调用次接口变更)
     * 本接口支持所有商户聚合商户（接口、平台进件商户）变更入账信息，双账户的修改的话需要对公和对私信息都需要上传（需人工审核），支持7省商户变更入账信息。
     * 图片使用4.2.3上传，返回图片id上传到本接口对应的字段中 接口中传值的字段必须参与签名，没传值的字段不参与签名。
     * @param array $data
     * @return array
     * @throws GuzzleException
     */
    public function mchntAcntUpdV2(array $data = []): array
    {
        $params = [
            'trace_no'                  => time() . '13',                                           //唯一流水号，机构自己定义，此字段可辅助拉取报文
            'fy_mchnt_cd'               => $data['fy_mchnt_cd'],                                    //已在富友入网的富友商户代码
            'ins_cd'                    => $this->insCd,                                            //机构号,接入机构在富友的唯一代码
            'dest_acnt_type'            => $data['dest_acnt_type'] ?? '01',                         //需要更改的结算卡类型 01 对公，02对私，04双账户
            'bank_type_s'               => $data['bank_type_s'] ?? '',                              //对私行别
            'inter_bank_no_s'           => $data['inter_bank_no_s'] ?? '',                          //对私入账卡开户行联行号见附件9 开户行信息列表
            'iss_bank_nm_s'             => $data['iss_bank_nm_s'] ?? '',                            //对私入账卡开户行（在联行号找不到时生效）
            'acnt_nm_s'                 => $data['acnt_nm_s'] ?? '',                                //对私入账卡户名
            'acnt_no_s'                 => $data['acnt_no_s'] ?? '',                                //对私入账卡号（不带长度位）
            'acnt_contact_mobile_s'     => $data['acnt_contact_mobile_s'] ?? '',                    //对私户入账手机号
            'prov_cd_s'                 => $data['prov_cd_s'] ?? '',                                //对私省代码
            'city_cd_s'                 => $data['city_cd_s'] ?? '',                                //对私市代码
            'bank_type_g'               => $data['bank_type_g'] ?? '',                              //对公行别
            'inter_bank_no_g'           => $data['inter_bank_no_g'] ?? '',                          //对公入账卡开户行联行号见附件9 开户行信息列表
            'iss_bank_nm_g'             => $data['iss_bank_nm_g'] ?? '',                            //对公入账卡开户行（在联行号找不到时生效）
            'acnt_nm_g'                 => $data['acnt_nm_g'] ?? '',                                //对私入账卡户名
            'acnt_no_g'                 => $data['acnt_no_g'] ?? '',                                //对公入账卡号（不带长度位）
            'prov_cd_g'                 => $data['prov_cd_g'] ?? '',                                //对公省代码
            'city_cd_g'                 => $data['city_cd_g'] ?? '',                                //对公市代码
            'acnt_certif_id'            => $data['acnt_certif_id'] ?? '',                           //入账人身份证号
            'acnt_certif_expire_dt'     => $data['acnt_certif_expire_dt'] ?? '',                    //到期日期
            'acnt_artif_flag'           => $data['acnt_artif_flag'] ?? '',                          //法人入账标识(0:非法人入账,1:法人入账若license_type=A，这此字段必须填：1:法人入账)
            'acnt_certif_tp'            => $data['acnt_certif_tp'] ?? '',                           //入账证件类型('0':'身份证'【默认】【acnt_artif_flag = 0时必填】
            'bank_front_img_id'         => $data['bank_front_img_id'] ?? '',                        //银行卡正面照 d2f8d0d0bfa8d5fdc3e6d5d5
            'public_act_img_id'         => $data['public_act_img_id'] ?? '',                        //对公户照片（开户许可证、印鉴卡、单位结算卡、开户回执、银行对账单、网银截图）b6d4b9abbba7d5d5c6ac
            'proof_mchnt_img_id'        => $data['proof_mchnt_img_id'] ?? '',                       //商户关系证明协议（入账非法人提供）c9ccbba7b9d8cfb5d6a4c3f7d0add2e9
            'card_bank_sc_img_id'       => $data['card_bank_sc_img_id'] ?? '',                      //身份证和银行卡手持证件照，开通D0业务需要上传 c9edb7ddd6a4bacdd2f8d0d0bfa8cad6b3d6d6a4bcfed5d5
            'private_card_front_img_id' => $data['private_card_front_img_id'] ?? '',                //对私账户身份证明正面 b6d4cbbdd5cbbba7c9edb7ddd6a4c3f7d5fdc3e6
            'private_card_back_img_id'  => $data['private_card_back_img_id'] ?? '',                 //对私账户身份证明背面 b6d4cbbdd5cbbba7c9edb7ddd6a4c3f7b1b3c3e6
            'certificate_flag'          => $data['certificate_flag'] ?? '',                         //1：电子协议（变更单必须走电子协议）可替代“入账非法人证明”材料
            'modify_desc'               => $data['modify_desc'] ?? "",                              //变更描述即变更备注，富友在审核时，可以看到的文字描述
        ];

        $url         = $this->mchntUrl . '?action=mchntAcntUpdV2';
        $responseStr = self::postDataXml($url, $params, 'GBK', 1);

        Log::info('4.2.2 入账信息变更接口v2请求返回：', ['url' => $url, 'data' => $data, 'responseStr' => $responseStr]);
        return $responseStr;
    }

    /**
     * 4.2.3 统一图片上传
     * 接口中传值的字段必须参与签名，没传值的字段不参与签名。 文件大小限制：单个附件大小不超过1MB 此接口用于入账信息变更的时候使用，只能上传单张图片，不是进件主流程的调用接口！！！
     *
     *  实际文件名为URLEncoder.encode(filename, 'GBK');之后去除百分号（%）//filename是文件中文名，不包含后缀
     * 例:filename为证件照片则中文文件名为【证件照片.jpg】,实际ZIP压缩包中文件名为【d6a4bcfed5d5c6ac.jpg】
     * 大小写不敏感
     * @param array $data
     * @return array
     */
    public function uploadImg(array $data = []): array
    {
        $params = [
            'trace_no'  => time() . '14',          //唯一流水号，机构自己定义，此字段可辅助拉取报文
            'ins_cd'    => $this->insCd,           //机构号,接入机构在富友的唯一代码
            'mchnt_cd'  => $data['mchnt_cd'],      //商户号
            'file_name' => $data['file_name'],     //文件名称(此处图片是什么格式 就对应什么后缀，例如xxx.png。)
            'file'      => $data['file'],          //图片文件
        ];

        $url         = $this->uploadUrl . '?action=uploadImg';
        $responseStr = self::formData($url, $params);

        Log::info('富友4.2.3 统一图片上传请求返回：', ['url' => $url, 'data' => $data, 'responseStr' => $responseStr]);
        return $responseStr;
    }

    /**
     * 统一图片上传-form-data
     * @param string $url
     * @param array $postData
     * @return array
     */
    public function formData(string $url, array $postData): array
    {
        $postData['sign'] = self::getSign($postData);
        $response         = Http::asMultipart()->post(
            $url, [
                [
                    'name'     => 'trace_no',
                    'contents' => $postData['trace_no']
                ],
                [
                    'name'     => 'ins_cd',
                    'contents' => $postData['ins_cd']
                ],
                [
                    'name'     => 'mchnt_cd',
                    'contents' => $postData['mchnt_cd']
                ],
                [
                    'name'     => 'file_name',
                    'contents' => $postData['file_name']
                ],
                [
                    'name'     => 'sign',
                    'contents' => $postData['sign']
                ],
                [
                    'name'     => 'file',
                    'contents' => fopen($postData['file'], 'r'),
                    'filename' => $postData['file_name']
                ]
            ]
        );

        $body = $response->body();
        Log::info('统一图片上传-form-data接口请求返回：', ['url' => $url, 'postData' => $postData, 'body' => json_decode($body, true)]);

        return json_decode($body, true);
    }
}
